<?php
declare (strict_types = 1);

namespace app\api\controller;

use think\Exception;
use think\exception\ValidateException;

use app\common\model\{User, UserAddress, Shop, Img, Order, Goods, Collect, FinancialRecord as Fin, PointTransRecord as PointRecord, Cash, Star};
use app\common\validate\{UserAddressValidate, ShopValidate};
use service\JsonService as Json;

class UserController extends BaseController
{
    /** 
     * 查询用户信息
     */
    public function getUserInfo()
    {
        $field = 'nickname, avatar, star, mobile, money, money_brokerage, money_red, money_healthy, point';
        $userInfo = User::getFind(['id' => $this->user_id], $field);
        if($userInfo === false) return Json::fail('用户不存在！');
        return Json::success('ok', $userInfo);
    }

    /**
     * 绑定银行卡
     */
    public function setBank()
    {
        $realName   = Request()->param('real_name', '');
        $bankName   = Request()->param('bank_name', '');
        $bankNumber = Request()->param('bank_number', '');
        if(empty($realName) || empty($bankName) || empty($bankNumber)) return Json::fail('数据错误！');

        $flag = User::edit(['id' => $this->user_id, 'real_name' => $realName, 'bank_name' => $bankName, 'bank_number' => $bankNumber]);

        if($flag === false) return Json::fail('绑定失败，请稍后重试！');
        return Json::fail('绑定成功');
    }

    /** 
     * 新增收货地址
     */
    public function addAddress()
    {
        $data = input('');

        try{
            validate(UserAddressValidate::class)->scene('add')->check($data);
        }catch(ValidateException $e){
            $this->error_back($e->getError());
        }

        if($data['is_default'] == 1){
            UserAddress::editWhere(['is_default' => 0], ['user_id' => $this->user_id]);
        }

        $data['user_id'] = $this->user_id;
        $flag = UserAddress::add($data);

        if($flag === false) return Json::fail('新增失败！');
        return Json::success('新增成功');
    }

    /** 
     * 编辑收货地址
     */
    public function setAddress()
    {
        $data = input('');

        try{
            validate(UserAddressValidate::class)->scene('set')->check($data);
        }catch(ValidateException $e){
            $this->error_back($e->getError());
        }

        if($data['is_default']){
            UserAddress::editWhere(['is_default' => 0], ['user_id' => $this->user_id]);
        }

        $flag = UserAddress::edit($data);

        if($flag === false) return Json::fail('编辑失败！');
        return Json::success('编辑成功');
    }

    /** 
     * 获取收货地址列表
     */
    public function getAddressList()
    {
        $list = UserAddress::getList(['user_id' => $this->user_id], 0, 0, 0, 'id, name, mobile, address, is_default', 'is_default DESC, id DESC');

        if($list === false) return Json::fail('暂无数据~');
        return Json::success('ok', $list);
    }

    /** 
     * 删除收货地址
     */
    public function delAddress()
    {
        $id = Request()->param('id', 0);
        $flag = UserAddress::del(['id' => $id]);

        if($flag === false) return Json::fail('删除失败！');
        return Json::success('删除成功');
    }

    /** 
     * 设置默认地址
     */
    public function setDefault()
    {
        $id = Request()->param('id', 0);

        UserAddress::editWhere(['is_default' => 0], ['user_id' => $this->user_id]);
        $flag = UserAddress::edit(['id' => $id, 'is_default' => 1]);

        if($flag === false) return Json::fail('设置失败！');
        return Json::success('设置成功');
    }

    /**
     * 申请加盟
     */
    public function applyShop()
    {
        $data = input('');

        try{
            validate(ShopValidate::class)->scene('add')->check($data);
        }catch(ValidateException $e){
            $this->error_back($e->getError());
        }

        $info = Shop::getFind(['user_id' => $this->user_id]);

        if($info !== false && $info->getData('status') != 2) return Json::fail('请勿重复申请');

        $data['user_id'] = $this->user_id;

        /** 开业时间 */
        $data['start_time'] = strtotime($data['start_time']);

        /** 红包额度 */
        $data['money_red'] = 0;
        $data['bond']      = 0;

        $flag = Shop::add($data);
        if($flag === false) return Json::fail('申请失败！');

        $doorImg = json_decode($data['door_img']);

        $doorImgArr = [];
        foreach($doorImg as $v){
            $doorImgArr[] = [
                'obj_type'    => 2,
                'obj_id'      => $flag->id,
                'obj_cate'    => 1,
                'img'         => $v,
                'create_time' => time(),
            ];
        }

        Img::addAll($doorImgArr);

        return Json::success('申请成功，请耐心等待审核。');
    }

    /**
     * 获取加盟信息
     */
    public function getMyShop()
    {
        $info = Shop::where(['user_id' => $this->user_id])->withoutField('user_id, delete_time, create_time')->order('id DESC')->find();
        if($info === false) return Json::fail('还未申请店铺');

        $doorImg = Img::getList(['obj_type' => 2, 'obj_cate' => 1, 'obj_id' => $info['id']], 0, 0);

        if($doorImg !== false){
            $doorImg = $doorImg->toArray();
            $info['door_img'] = array_column($doorImg, 'img');
        }else{
            $info['door_img'] = [];
        }

        
        return Json::success('ok', $info);
    }

    /**
     * 我的订单
     */
    public function getOrderList()
    {
        $status = Request()->param('status', 0);
        $page   = Request()->param('page', 0);

        $list = Order::getOrderList($this->user_id, $status, $page);

        if($list === false) return Json::fail('暂无数据~');
        return Json::success('ok', $list);
    }

    /**
     * 取消订单
     */
    public function orderCancel()
    {
        $orderId = Request()->param('order_id', 0);

        $info = order::getFind(['id' => $orderId]);

        if($info === false) return Json::fail('订单不存在！');
        if($info->getData('status') == 4) return Json::fail('请勿重复取消！');
        if($info->getData('status') !== 0) return Json::fail('订单不能取消！');

        $flag = order::edit(['id' => $orderId, 'status' => 4]);

        if($flag === false) return Json::fail('取消失败！');
        return Json::success('取消成功');
    }

    /**
	 * 收藏
	 */
    public function setCollect()
    {
        $objId = Request()->param('obj_id', 0);
        $type  = Request()->param('type', 1);

        $data = [
            'user_id'  => $this->user_id,
            'obj_id'   => $objId,
            'obj_type' => $type,
        ];

        $info = Collect::getFind($data);
        if($info !== false) return Json::fail('已收藏');
        
        $flag = Collect::add($data);

        if($flag === false) return Json::fail('收藏失败！');
        return Json::success('收藏成功');
    }

    /**
     * 我的收藏
     */
    public function getMyCollectList()
    {
        $type = Request()->param('type', 1);
        $page = Request()->param('page', 1);

        $ids = Collect::getCol(['obj_type' => $type], 'obj_id');
        if($ids === false) return Json::fail('暂无数据~');

        $where[] = ['id', 'in', $ids];

        switch($type){
            case 1:
                $list = Shop::getList($where, 1, $page, 10, 'id, name, business_time, address, brief');
                break;
            case 2:
                $list = Goods::getList($where, 1, $page, 10, 'id, name, small_img, price');
                break;
            case 3:
                $list = '还没写';
                break;
            default:
                return Json::fail('类型错误！');
                break;
        }

        if($list === false) return Json::fail('暂无数据~');
        return Json::success('ok', $list);
    }

    /**
	 * 取消收藏
	 */
    public function delCollect()
    {
        $objId = Request()->param('obj_id', 0);
        $type  = Request()->param('type', 1);

        $where = [
            'user_id'  => $this->user_id,
            'obj_id'   => $objId,
            'obj_type' => $type,
        ];

        $flag = Collect::del($where);
        return Json::success('取消收藏成功');
    }

    /**
     * 财务记录
     */
    public  function getMoneyList()
    {
        $type   = Request()->param('type', 0);
        $status = Request()->param('status', 0);
        $page   = Request()->param('page', 0);

        if($type == 0 || $status == 0 || $page == 0) return Json::fail('数据错误！');

        $where[] = ['user_id', '=', $this->user_id];
        $where[] = ['money_type', '=', $type];
        
        if($status == 1){
            $where[] = ['num', '>', 0];
        }else if($status == 2){
            $where[] = ['num', '<', 0];
        }else{
            return Json::fail('数据错误！');
        }

        $field = 'id, content, num, create_time';
        $list = Fin::getList($where, 1, $page, 20, $field, 'create_time DESC');

        switch ($type) {
            case 1:
                $backData = [
                    'money'              => 0,
                    'money_to_brokerage' => 0,
                    'charge_money'       => 0,
                    'total_revenue'      => 0,
                    'total_expend'       => 0,
                ];
                break;
            case 2:
                $backData = [
                    'money_brokerage'    => 0,
                    'brokerage_to_money' => 0,
                    'brokerage_consume'  => 0,
                    'brokerage_frozen'   => 0,
                    'brokerage_cash'     => 0,
                    'total_revenue'      => 0,
                    'total_expend'       => 0,
                ];
                break;
            case 3:
                $backData = [
                    'money_red'          => 0,
                    'red_consume'        => 0,
                    'red_sign'           => 0,
                    'total_save'         => 0,
                    'total_revenue'      => 0,
                    'total_expend'       => 0,
                ];
                break;
            case 4:
                $backData = [
                    'point'              => 0,
                    'total_revenue'      => 0,
                    'total_expend'       => 0,
                ];
                break;
            case 5:
                $backData = [
                    'money_healthy'      => 0,
                    'total_revenue'      => 0,
                    'total_expend'       => 0,
                ];
                break;
            default:
                $backData = [];
                break;
        }

        if($list === false) return Json::fail('暂无数据~');

        $backData['list'] = $list;
        return Json::success('ok', $backData);
    }

    /**
     * 转让积分
     */
    public function transPoint()
    {
        $toMobile = Request()->param('to_mobile', '');
        $num      = Request()->param('num', 0);

        if(empty($toMobile) || $num == 0) return Json::fail('数据错误！');

        $toUserInfo = User::getFind(['mobile' => $toMobile]);
        if($toUserInfo === false) return Json::fail('手机号不存在');
        if($toUserInfo['id'] == $this->user_id) return Json::fail('不能给自己转！！！');

        $userInfo = User::getFind(['id' => $this->user_id]);
        
        if($userInfo['point'] < $num) return Json::fail('积分不足！');

        self::beginTrans();
        try {
            $flag = PointRecord::add([
                'user_id'    => $this->user_id,
                'to_user_id' => $toUserInfo['id'],
                'num'        => $num,
                'back_days'  => getSystemVal()['point_back_days'],
            ]);
    
            if($flag === false) throw new Exception('转让失败，请稍后重试!');

            /** 转让方积分冻结 */
            if(User::setDecField(['id' => $this->user_id], 'point', $num) === false) throw new Exception('扣除积分失败，请稍后重试！');
            if(User::setIncField(['id' => $this->user_id], 'point_frozen', $num) === false) throw new Exception('冻结积分失败，请稍后重试！');

            self::commitTrans();
        } catch (\Exception $e) {
            self::rollbackTrans();
            return Json::fail($e->getMessage());
        }
        
        return Json::success('转让成功，等待对方接受');
    }

    /**
     * 转让记录
     */
    public function getTransPointRecord()
    {
        $status = Request()->param('status', 0);
        $page   = Request()->param('page', 0);
        if($status == 0 || $page == 0) return Json::fail('数据错误！');

        if($status == 1){
            $fromUserId = 'user_id';
            $toUserId   = 'to_user_id';
            $status = ['待接受', '确认转出', '已完成', '已撤销'];
        }else if($status == 2){
            $fromUserId = 'to_user_id';
            $toUserId   = 'user_id';
            $status = ['接受', '待确认', '已完成', '已撤销'];
        }else{
            return Json::fail('数据错误！');
        }

        $where[$fromUserId] = $this->user_id;
        $field = 'id, ' . $toUserId . ', num, status, create_time';
        $list = PointRecord::getList($where, 1, $page, 20, $field, 'status, create_time DESC');
        
        if($list === false) return Json::fail('暂无数据~');

        foreach($list as &$info){
            $toUserInfo = User::getFind(['id' => $info[$toUserId]]);

            $info['user_name']   = $toUserInfo['nickname'];
            $info['user_avatar'] = $toUserInfo['avatar'];
            $info['status']      = $status[$info['status'] - 1];
            unset($info[$toUserId]);
        }

        return Json::success('ok', $list);
    }

    /**
     * 积分转让-接受
     */
    public function transPointAccept()
    {
        $pointRecordId   = Request()->param('point_record_id', 0);
        if($pointRecordId == 0) return Json::fail('数据错误！');

        $pointRecordInfo = PointRecord::getFind(['id' => $pointRecordId]);
        if($pointRecordInfo === false) return Json::fail('数据不存在！');
        if($pointRecordInfo['to_user_id'] != $this->user_id) return Json::fail('数据不存在！');
        if($pointRecordInfo['status'] != 1) return Json::fail('数据状态错误！');

        $flag = PointRecord::edit(['id' => $pointRecordId, 'status' => 2]);
        if($flag === false) return Json::fail('修改状态失败');
        return Json::fail('接受成功，等待对方再次确认');
    }

    /**
     * 积分转让-拒收
     */
    public function transPointRefuse()
    {
        $pointRecordId = Request()->param('point_record_id', 0);
        if($pointRecordId == 0) return Json::fail('数据错误！');

        $pointRecordInfo = PointRecord::getFind(['id' => $pointRecordId]);
        if($pointRecordInfo === false) return Json::fail('数据不存在！');
        if($pointRecordInfo['to_user_id'] != $this->user_id) return Json::fail('数据不存在！');
        if($pointRecordInfo['status'] != 1) return Json::fail('数据状态错误！');

        self::beginTrans();
        try {
            if(PointRecord::edit(['id' => $pointRecordId, 'status' => 4]) === false) throw new Exception('修改状态失败');

            /** 返还转让方冻结积分 */
            if(User::setDecField(['id' => $pointRecordInfo['user_id']], 'point_frozen', $pointRecordInfo['num']) === false) throw new Exception('扣除冻结积分失败，请稍后重试！');
            if(User::setIncField(['id' => $pointRecordInfo['user_id']], 'point', $pointRecordInfo['num']) === false) throw new Exception('积分增加失败，请稍后重试！');

            self::commitTrans();
        } catch (\Exception $e) {
            self::rollbackTrans();
            return Json::fail($e->getMessage());
        }

        return Json::fail('拒绝成功');
    }

    /**
     * 积分转让-确认转出
     */
    public function transPointConfirm()
    {
        $pointRecordId = Request()->param('point_record_id', 0);
        if($pointRecordId == 0) return Json::fail('数据错误！');

        $pointRecordInfo = PointRecord::getFind(['id' => $pointRecordId]);
        if($pointRecordInfo === false) return Json::fail('数据不存在！');
        if($pointRecordInfo['user_id'] != $this->user_id) return Json::fail('数据不存在！');
        if($pointRecordInfo['status'] != 2) return Json::fail('数据状态错误！');

        self::beginTrans();
        try {
            if(PointRecord::edit(['id' => $pointRecordId, 'status' => 3]) === false) throw new Exception('修改状态失败');

            /** 转让积分 */
            if(User::setDecField(['id' => $this->user_id], 'point_frozen', $pointRecordInfo['num']) === false) throw new Exception('扣除积分失败，请稍后重试！');
            if(Fin::adds($this->user_id, $pointRecordId, 3, 3, '积分转出', '-' . $pointRecordInfo['num']) === false) throw new Exception('添加财务记录失败！');

            if(User::setIncField(['id' => $pointRecordInfo['to_user_id']], 'point', $pointRecordInfo['num']) === false) throw new Exception('积分增加失败，请稍后重试！');
            if(Fin::adds($pointRecordInfo['to_user_id'], $pointRecordId, 3, 3, '积分转入', $pointRecordInfo['num']) === false) throw new Exception('添加财务记录失败！');

            self::commitTrans();
        } catch (\Exception $e) {
            self::rollbackTrans();
            return Json::fail($e->getMessage());
        }

        return Json::fail('转出成功');
    }

    /**
     * 积分转让-取消转出
     */
    public function transPointCancel()
    {
        $pointRecordId = Request()->param('point_record_id', 0);
        if($pointRecordId == 0) return Json::fail('数据错误！');

        $pointRecordInfo = PointRecord::getFind(['id' => $pointRecordId]);
        if($pointRecordInfo === false) return Json::fail('数据不存在！');
        if($pointRecordInfo['user_id'] != $this->user_id) return Json::fail('数据不存在！');
        if($pointRecordInfo['status'] > 2) return Json::fail('数据状态错误！');

        self::beginTrans();
        try {
            if(PointRecord::edit(['id' => $pointRecordId, 'status' => 4]) === false) throw new Exception('修改状态失败');

            /** 返还冻结积分 */
            if(User::setDecField(['id' => $this->user_id], 'point_frozen', $pointRecordInfo['num']) === false) throw new Exception('扣除冻结积分失败，请稍后重试！');
            if(User::setIncField(['id' => $this->user_id], 'point', $pointRecordInfo['num']) === false) throw new Exception('积分增加失败，请稍后重试！');

            self::commitTrans();
        } catch (\Exception $e) {
            self::rollbackTrans();
            return Json::fail($e->getMessage());
        }

        return Json::fail('取消成功');
    }

    /**
     * 佣金提现
     */
    public function cashBrokerage()
    {
        $type = Request()->param('type', 0);
        $num  = Request()->param('num', 0);
        if($type == 0 || $num == 0) return Json::fail('数据错误！');

        $userInfo = User::getFind(['id' => $this->user_id]);
        if($type == 2 && (empty($userInfo['real_name']) || empty($userInfo['bank_name']) || empty($userInfo['bank_number']))) return Json::fail('请完善银行卡信息');

        $cashFee = Star::getVal(['grade' => $userInfo->getData('star')], 'cash_fee');
        if($userInfo['money_brokerage'] < $num * $cashFee + $num) return Json::fail('佣金余额不足！');

        self::beginTrans();
        try {
            $flag = Cash::add(['user_id' => $this->user_id, 'num' => $num, 'type' => $type, 'cash_fee' => $cashFee]);
            if($flag === false) return Json::fail('提现失败，请稍后重试！');

            /** 佣金冻结 */
            if(User::setDecField(['id' => $this->user_id], 'money_brokerage', $num * $cashFee + $num) === false) throw new Exception('扣除佣金失败，请稍后重试！');
            if(User::setIncField(['id' => $this->user_id], 'money_brokerage_frozen', $num * $cashFee + $num) === false) throw new Exception('冻结佣金失败，请稍后重试！');

            self::commitTrans();
        } catch (\Exception $e) {
            self::rollbackTrans();
            return Json::fail($e->getMessage());
        }

        return Json::fail('提交成功');
    }

    /**
     * 测试支付回调
     */
    public function notify()
    {
        // $data = User::pushAward(1, 1000, 1);
        $data = User::reckonGrade(3);
        return Json::success('ok', $data);
    }

    public function aa()
    {
        
    }
}